/*
 * detection.c - detection related
 * Clunix, KyungWoon Cho, cezanne@clunix.com, 2006.2
 *
 * Copyright (c) 2001-2008 by Clunix Inc. All Rights Reserved.
 */

#include "config.h"

#include "ebcd.h"

ecm_int32	ebcd_detection_interval;

static ecm_thread_t	detecter;

static ecm_mutex_t	mutex;
static ecm_cond_t	cond;

static ECMBOOL stopping_detecter;

static ebc_pktb_t	*pktb_detection;

static void
build_detection_pktb(void)
{
	ebc_addr_t	daddr;
	ebc_msgt_t	msgt;

	ebc_build_addr(&daddr, "*", "ebcd", NULL);
	msgt = EBC_MSGT_REQ | EBC_MSGT_DETECT | EBC_MSGT_ONEWAY;
	pktb_detection = ebcd_build_pktb(NULL, &daddr, NULL, msgt);
}

static void
send_detection_pktb(void)
{
	pch_send_pktb(dpch_bdcast->pchp, pktb_detection);
}

static void
do_detection(ecm_ptr_t arg)
{
	ecm_uint32	detection_interval = ebcd_detection_interval;

	send_detection_pktb();

	if (detection_interval == 0)
			detection_interval = EBCD_DEFAULT_DETECTION_INTERVAL;

	ecm_mutex_lock(mutex);
	while (!stopping_detecter) {
		ecm_uint32	timeout = detection_interval;

		send_detection_pktb();
		do_active_detection();
		ecm_cond_wait(cond, mutex, &timeout);
	}
	ecm_mutex_unlock(mutex);
}

void
ebcd_start_detecter(void)
{
	if (ebcd_detection_interval < 0)
		return;

	build_detection_pktb();
	mutex = ecm_mutex_create(ECM_FALSE);
	cond = ecm_cond_create();
	stopping_detecter = ECM_FALSE;
	ecm_thread_create(&detecter, do_detection, NULL);
}

void
ebcd_stop_detecter(void)
{
	if (ebcd_detection_interval < 0)
		return;

	ecm_mutex_lock(mutex);
	stopping_detecter = ECM_TRUE;
	ecm_cond_signal(cond);
	ecm_mutex_unlock(mutex);

	ecm_thread_free(detecter);
	ecm_mutex_free(mutex);
	ecm_cond_free(cond);

	ebc_pktb_free(pktb_detection);
	pktb_detection = NULL;
}
